﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace ExamRepositoryWebAPI.DataRepositories
{
    public interface IRepository<TEntity, TPrimaryKey> where TEntity:class
    {
        #region 查询
        IQueryable<TEntity> GetAll();

        List<TEntity> GetAllList();

        Task<List<TEntity>> GetAllListAsync();

        List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate);

        Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 通过筛选条件获取实体信息
        /// 如果查询不到返回值，引发异常
        /// </summary>
        TEntity Single(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 通过筛选条件获取实体信息
        /// 如果查询不到返回值，引发异常
        /// </summary>
        Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 通过筛选条件获取实体信息
        /// 如果查询不到返回值，返回null
        /// </summary>
        TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 通过筛选条件获取实体信息
        /// 如果查询不到返回值，返回null
        /// </summary>
        Task<TEntity> FirstOrDefualtAsync(Expression<Func<TEntity, bool>> predicate);
        #endregion
        #region 增加
        TEntity Insert(TEntity entity);

        Task<TEntity> InsertAsync(TEntity entity);


        #endregion
        #region 修改
        TEntity Upadate(TEntity entity);

        Task<TEntity> UpdateAsync(TEntity entity);
        #endregion
        #region 删除
        void Delete(TEntity entity);

        Task DeleteAsync(TEntity entity);

        void Delete(Expression<Func<TEntity, bool>> predicate);

        Task DeleteAsync(Expression<Func<TEntity, bool>> predicate);
        #endregion
        #region 统计
        int Count();

        Task<int> CountAsync();

        int Count(Expression<Func<TEntity, bool>> predicate);

        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate);

        long LongCount();

        Task<long> LongCountAsync();

        long LongCount(Expression<Func<TEntity, bool>> predicate);

        Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate);
        #endregion
    }
}
